package engine.res;

import java.nio.FloatBuffer;
import math.Maths;
import util.Util;
import static engine.GL.*;

public class Color 
{

    public static final Color WHITE = new Color(1, 1, 1, 1f);
    public static final Color BLACK = new Color(0, 0, 0, 1f);
    public static final Color RED = new Color(1, 0, 0, 1f);
    public static final Color GREEN = new Color(0, 1, 0, 1f);
    public static final Color BLUE = new Color(0, 0, 1, 1f);
    public static final Color YELLOW = new Color(1, 1, 0, 1f);
    public static final Color CYAN = new Color(0, 1, 1, 1f);
    public static final Color MAGENTA = new Color(1, 0, 1, 1f);
    public static final Color WHITE_TRANSPARENT = new Color(1, 1, 1, 0f);
    public static final Color BLACK_TRANSPARENT = new Color(0, 0, 0, 0f);
    public static final Color GREY_01 = new Color(0.1, 0.1, 0.1, 1f);
    public static final Color GREY_02 = new Color(0.2, 0.2, 0.2, 1f);
    public static final Color GREY_03 = new Color(0.3, 0.3, 0.3, 1f);
    public static final Color GREY_04 = new Color(0.4, 0.4, 0.4, 1f);
    public static final Color GREY_05 = new Color(0.5, 0.5, 0.5, 1f);
    public static final Color GREY_06 = new Color(0.6, 0.6, 0.6, 1f);
    public static final Color GREY_07 = new Color(0.7, 0.7, 0.7, 1f);
    public static final Color GREY_08 = new Color(0.8, 0.8, 0.8, 1f);
    public static final Color GREY_09 = new Color(0.9, 0.9, 0.9, 1f);
    
    public float r;
    public float g;
    public float b;
    public float a;

    public Color(float red, float green, float blue, float alpha) 
    {
        r = red;
        g = green;
        b = blue;
        a = alpha;
    }

    public Color(float red, float green, float blue) 
    {
        this(red, green, blue, 1);
    }

    public Color(double red, double green, double blue) 
    {
        this((float) red, (float) green, (float) blue, 1);
    }

    public Color(double red, double green, double blue, double alpha) 
    {
        this((float) red, (float) green, (float) blue, (float) alpha);
    }
    
    public Color(int red, int green, int blue, int alpha) 
    {
        this(
            red * Maths.ONE_OVER_255, 
            green * Maths.ONE_OVER_255, 
            blue * Maths.ONE_OVER_255, 
            alpha * Maths.ONE_OVER_255
        );
    }

    public Color(Color col) 
    {
        this(col.r, col.g, col.b, col.a);
    }
    
    public void bind() 
    {
        color(this);
    }

    public void setTransparent() 
    {
        if (a != 0) 
        {
            a = 0;
        }
    }

    public void setOpaque() 
    {
        if (a != 1) 
        {
            a = 1;
        }
    }
    
    public boolean isCloseTo(Color other) 
    {
        float epsilon = 0.05f; // 5% difference between other and this
        boolean diffr = Maths.abs(r - other.r) <= epsilon;
        boolean diffg = Maths.abs(g - other.g) <= epsilon;
        boolean diffb = Maths.abs(b - other.b) <= epsilon;
        boolean diffa = Maths.abs(a - other.a) <= epsilon;
        return (diffr && diffg && diffb && diffa);
    }
    
    public Color getCopyOfTransparency(double alpha) 
    {
        return getCopyOfTransparency((float) alpha);
    }
    
    public Color getCopyOfTransparency(float alpha) 
    {
        return new Color(r, g, b, alpha);
    }

    public Color getTransparentCopy() 
    {
        return new Color(r, g, b, 0.0f);
    }

    public Color getOpaqueCopy() 
    {
        return new Color(r, g, b, 1.0f);
    }
    
    public float[] getAsArray() 
    {
        return new float[] { r, g, b, a };
    }
    
    public FloatBuffer getAsFloatBuffer() 
    {
        return Util.getFloatBuf(getAsArray());
    }
    
    public String toString() 
    {
        String s = "";
        s += "( " + r + ", " + g + ", " + b + ", " + a + " )";
        return s;
    }

}
